初学redis分页缓存方法实现

您所在的位置:网站首页 redis分页查询 node 初学redis分页缓存方法实现

初学redis分页缓存方法实现

2023-08-08 19:23| 来源: 网络整理| 查看: 265

初学redis分页缓存方法实现

使用缓存技术一般是在不经常增删改查的数据,我们可以使用缓存技术将第一次请求访问的数据缓存到redis中保存起来,后来的请求的时候首先查询redis数据库是否查询到这些数据,如果存在,则返回数据,如果不存在,则到mysql或其他数据库查询数据返回并保存到redis数据库中。

为什么要采用分页缓存?直接设置缓存,如果数据量大,操作增删改,更新缓存频率高效率低。分页缓存,通过页码设置缓存,可以提高性能。(但是其实不是很好)。

缓存的时候需要考虑的一些问题:

1.新增--删除最后一页缓存(如果倒叙排序,插入数据,第一页改变,后续页列表也都改变,需要删除所有缓存)。 2.修改--更新当前页缓存。 3.删除--更新当前页以及当前页以后的页面的缓存。

上面是分页缓存实现的时候要考虑的一些问题,而我在下面实现的代码并不是这样的,因为我懒得传当前页面cuePage了在add、delete、update的时候,所以,我选择了在add、delete、update的时候都把缓存的分页缓存相关key请理了,更新了分页缓存数据。

    @RequestMapping({"/","index"})     public String index(Model model,             @RequestParam(value = "curPage",required = false,defaultValue ="1") Integer curPage){         //每页展示10条数据         int pageSize = 5;         //总数         int totalRows = userService.getUserByTotal();         //计算分页         int totalPages = totalRows / pageSize;         //可能有余页         int left = totalRows % pageSize;         if (left > 0){             totalPages = totalPages + 1;         }         if (curPage  totalPages ){             curPage = totalPages;         }         //计算查询的开始行         int startRow = (curPage - 1) * pageSize;         Map paramMap = new ConcurrentHashMap();         paramMap.put("startRow",startRow);         paramMap.put("pageSize",pageSize);         paramMap.put("curPage",curPage);//第几页         List userList = userService.getUserBypage(paramMap);         System.out.println("curPage:"+curPage);         model.addAttribute("userList",userList);         model.addAttribute("curPage",curPage);         model.addAttribute("totalPages",totalPages);         //跳转到模板页面         return "index";     }

实现类,缓存总页数。

    @Override     public int getUserByTotal() {         System.out.println("test:"+userMapper.selectUserByTotal());         //设置key的序列化方式,采用字符串方式,提高可读性         redisTemplate.setKeySerializer(new StringRedisSerializer());         //先从Redis缓存查询         Integer totalRows = (Integer) redisTemplate.opsForValue().get("totalRows");         if (null == totalRows){             synchronized (this){                 totalRows = (Integer) redisTemplate.opsForValue().get("totalRows");                 if (null == totalRows){                     //去mysql数据库查询总数,并保存到redis缓存中                     totalRows = userMapper.selectUserByTotal();                     redisTemplate.opsForValue().set("totalRows",totalRows);                     System.out.println("从mysql数据库获取totalRows");                 }             }         }         return totalRows;     }

查询分页缓存,按照查询当前页进行缓存。缓存在redis数据库中的key="curPage1"、key="curPage2"、key="curPage3"、key="curPage*"。

    @Autowired     private UserMapper userMapper;     @Autowired     private RedisTemplate redisTemplate;     @Override     public List getUserBypage(Map paramMap) {         //设置key的序列化方式,采用字符串方式,提高可读性         redisTemplate.setKeySerializer(new StringRedisSerializer());         Integer curPage = (Integer) paramMap.get("curPage");         List userList = (List) redisTemplate.opsForValue().get("curPage"+String.valueOf(curPage));         if (null == userList){             userList = userMapper.selectUserBypage(paramMap);             redisTemplate.opsForValue().set("curPage"+String.valueOf(curPage),userList);             System.out.println("从mysql数据库获取userList");         }         return userList;     }

add。添加成功后,mysql数据库+1,redis缓存数据库需要更新一下数据总数的缓存,mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。

  @Override     public int addUser(User user) {         //设置key的序列化方式,采用字符串方式,提高可读性         redisTemplate.setKeySerializer(new StringRedisSerializer());         int add = userMapper.insertSelective(user);         if (add > 0){             //添加成功后,mysql数据库+1,redis缓存数据库需要更新一下数据             int totalRows = userMapper.selectUserByTotal();             redisTemplate.opsForValue().set("totalRows",totalRows);             //更新缓存             Set keys = redisTemplate.keys("curPage"+"*");             redisTemplate.delete(keys);         }         return add;     }

delete。删除成功后,mysql数据库-1,redis缓存数据库需要更新一下数据总数的缓存,mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。

 @Override     public int deleteUser(Integer id) {         //设置key的序列化方式,采用字符串方式,提高可读性         redisTemplate.setKeySerializer(new StringRedisSerializer());         int delete =  userMapper.deleteByPrimaryKey(id);         if (delete > 0){             //删除成功后,mysql数据库-1,redis缓存数据库需要更新一下数据             int totalRows = userMapper.selectUserByTotal();             redisTemplate.opsForValue().set("totalRows",totalRows);             //更新缓存             Set keys = redisTemplate.keys("curPage"+"*");             redisTemplate.delete(keys);         }         return delete;     }

update。update后mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。

    @Override     public int updateUser(User user) {         //设置key的序列化方式,采用字符串方式,提高可读性         redisTemplate.setKeySerializer(new StringRedisSerializer());         //boolean b = redisTemplate.delete("curPage"+"*");//         Set keys = redisTemplate.keys("curPage"+"*");         redisTemplate.delete(keys);         return userMapper.updateByPrimaryKey(user);     }

redisTemplate模糊匹配删除

        Set keys = redisTemplate.keys("curPage"+"*");         redisTemplate.delete(keys);         return userMapper.updateByPrimaryKey(user);

下面这样不行的,当时一直很疑惑,只能更新第一页的缓存,后面页的进行add、delete、update后都没有更新。所有百度一下,换了这么的删除key的方法,是可以的。

edisTemplate.delete("curPage"+"*");//这样不行

 

上面代码的实现缓存并不是很好,缓存需要优雅的使用,并不是所有的项目都需要缓存技术,在使用缓存之前,需要确认你的项目是否真的需要缓存,使用缓存会引入一定的技术复杂度。笔者在这里只是在学习缓存技术时,学习过程中的一些思考与记录。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3